1 package org.smartcomps.twister.util; 2 3 import org.smartcomps.twister.engine.priv.core.definition.impl.PropertyImpl; 4 5 import org.apache.commons.logging.Log; 6 import org.apache.commons.logging.LogFactory; 7 8 import java.util.HashMap; 9 import java.util.Date; 10 import java.util.Collection; 11 import java.util.ArrayList; 12 import java.lang.reflect.Method; 13 import java.lang.reflect.InvocationTargetException; 14 15 /*** 16 * This class simply gives a random value to all properties of a JavaBean and 17 * memorize it so that it can test, later on (after it has been persisted 18 * and reloaded for exemple), that original values are still same. 19 */ 20 public class BeanTester { 21 22 private static Log log = LogFactory.getLog(BeanTester.class); 23 24 public static final int STRING_LENGTH = 10; 25 26 private static final long FIFTY_YEARS_MS = 50*360*24*60*60*1000L; 27 private static final String SET_PREFIX = "set"; 28 private static final String GET_PREFIX = "get"; 29 private static final String IS_PREFIX = "is"; 30 31 private HashMap beansValues = new HashMap(); 32 private Collection ignoreList = null; 33 34 /*** 35 * Default constructor. 36 */ 37 public BeanTester() { 38 ignoreList = new ArrayList(); 39 } 40 41 /*** 42 * Creates a BeanTester with a list of properties that will be ignored. The 43 * BeanTester won't therefore try to assign those properties a value to test 44 * it later on. The first letter of each property must be in high case. 45 * @param ignoreList 46 */ 47 public BeanTester(String[] ignoreList) { 48 this.ignoreList = new ArrayList(ignoreList.length); 49 for (int m = 0; m < ignoreList.length; m++) { 50 String ignoreArg = ignoreList[m]; 51 this.ignoreList.add(ignoreArg); 52 } 53 } 54 55 /*** 56 * Lets the BeanTester initialize all properties of a bean. It isolates all 57 * properties of an object (basically from get and set methods following the 58 * JavaBean specs and accepting simple types (String, Integer, Date, Long, 59 * Boolean)) that aren't in the ignore list and sets them with a random value. 60 * @param name all objects tested by the BeanTester must be named 61 * @param bean object to test 62 */ 63 public void initializeProperties(String name, Object bean) { 64 Method[] beanMethods = bean.getClass().getMethods(); 65 for (int m = 0; m < beanMethods.length; m++) { 66 Method beanMethod = beanMethods[m]; 67 String propName = isProperty(beanMethod); 68 if (propName != null && !ignoreList.contains(propName)) { 69 Object rndValue = generateRandomValue(beanMethod.getParameterTypes()[0]); 70 if (rndValue != null) { 71 boolean setted = false; 72 try { 73 beanMethod.invoke(bean, new Object[]{rndValue}); 74 setted = true; 75 } catch (IllegalAccessException e) { 76 throw new RuntimeException("Could not invoke set" + propName + " with value " + 77 rndValue + " on object named " + name, e); 78 } catch (IllegalArgumentException e) { 79 throw new RuntimeException("Could not invoke set" + propName + " with value " + 80 rndValue + " on object named " + name, e); 81 } catch (InvocationTargetException e) { 82 log.warn("Could not invoke set" + propName + " with value " + 83 rndValue + " on object named " + name); 84 } 85 if (setted) { 86 log.info("Testing bean property " + propName + " for " + name); 87 beansValues.put(bean.getClass() + "(" + name + ")." + propName, rndValue); 88 } 89 } 90 } 91 } 92 } 93 94 /*** 95 * Tests the values of the properties that have been initialized 96 * @param name must have the same value as for initialization 97 * @param bean to test values 98 * @return true if all properties have the same values in the provided bean 99 */ 100 public boolean testValues(String name, Object bean) { 101 boolean result = true; 102 103 Method[] beanMethods = bean.getClass().getMethods(); 104 for (int m = 0; m < beanMethods.length; m++) { 105 Method beanMethod = beanMethods[m]; 106 String propName = isProperty(beanMethod); 107 if (propName != null && !ignoreList.contains(propName)) { 108 Object originalValue = beansValues.get(bean.getClass() + "(" + name + ")." + propName); 109 if (originalValue != null) { 110 Object currValue = null; 111 try { 112 Method getter = null; 113 try { 114 getter = bean.getClass().getMethod(GET_PREFIX + propName, new Class[]{}); 115 } catch (NoSuchMethodException e) { 116 getter = bean.getClass().getMethod(IS_PREFIX + propName, new Class[]{}); 117 } 118 currValue = getter.invoke(bean, new Object[]{}); 119 } catch (NoSuchMethodException e) { 120 throw new RuntimeException("Could not find get" + propName + " on object named " + name, e); 121 } catch (SecurityException e) { 122 throw new RuntimeException("Could not find get" + propName + " on object named " + name, e); 123 } catch (IllegalAccessException e) { 124 throw new RuntimeException("Could not invoke get" + propName + " on object named " + name, e); 125 } catch (InvocationTargetException e) { 126 throw new RuntimeException("Could not invoke get" + propName + " on object named " + name, e); 127 } 128 129 if (originalValue == null) { 130 if (currValue != null) { 131 result = false; 132 log.warn("Property " + propName + " changed, before " + originalValue +", now " + currValue); 133 } 134 } else if (!originalValue.equals(currValue)) { 135 result = false; 136 log.warn("Property " + propName + " changed, before " + originalValue +", now " + currValue); 137 } 138 } 139 } 140 } 141 142 return result; 143 } 144 145 public static Object generateRandomValue(Class aClass) { 146 Object result = null; 147 148 double rand = Math.random(); 149 if (aClass.equals(String.class)) { 150 result = "" + Math.round(rand * Math.pow(10, STRING_LENGTH)); 151 } else if (aClass.equals(Integer.TYPE)) { 152 result = new Integer(new Long(Math.round(rand * Integer.MAX_VALUE)).intValue()); 153 } else if (aClass.equals(Long.TYPE)) { 154 result = new Long(Math.round(rand * Integer.MAX_VALUE)); 155 } else if (aClass.equals(Boolean.TYPE)) { 156 result = new Boolean(rand < 0.5); 157 } else if (aClass.equals(Date.class)) { 158 result = new Date(Math.round(rand * FIFTY_YEARS_MS)); 159 } 160 161 return result; 162 } 163 164 private String isProperty(Method method) { 165 166 // Isolate a property from its set method 167 if (!method.getName().startsWith(SET_PREFIX)) { 168 return null; 169 } 170 171 // If setter has not exactly one parameter, it's not a right setter 172 if (method.getParameterTypes().length == 0 || method.getParameterTypes().length > 1) { 173 return null; 174 } 175 176 if (Collection.class.isAssignableFrom(method.getParameterTypes()[0])) { 177 return null; 178 } 179 180 // Must have a getter with same name 181 String propertyName = method.getName().substring(3); 182 Method correspondingGet = null; 183 Method[] methods = method.getDeclaringClass().getMethods(); 184 for (int m = 0; m < methods.length; m++) { 185 Method anotherMethod = methods[m]; 186 String anMethName = anotherMethod.getName(); 187 if (anMethName.equals(GET_PREFIX + propertyName) || anMethName.equals(IS_PREFIX + propertyName)) { 188 if (anotherMethod.getParameterTypes().length == 0) { 189 correspondingGet = anotherMethod; 190 } 191 } 192 } 193 if (correspondingGet == null) return null; 194 195 // Getter must return something 196 if (correspondingGet.getReturnType() == null) return null; 197 198 // Getter must return same type has setter accepts 199 if (!correspondingGet.getReturnType().equals(method.getParameterTypes()[0])) { 200 return null; 201 } 202 203 return propertyName; 204 } 205 206 // public static void main(String[] args) { 207 // BeanTester tester = new BeanTester(new String[] {"Id"}); 208 // PropertyImpl testBean = new PropertyImpl(); 209 // testBean.setName("aName"); 210 // testBean.setType("aType"); 211 // 212 // tester.initializeProperties("testBean", testBean); 213 // testBean.setId(new Long(12)); 214 // testBean.setName("anotherName"); 215 // System.out.println("Result : " + tester.testValues("testBean", testBean)); 216 // } 217 }

This page was automatically generated by Maven